#pragma once
#include <functional>
#include <vector>
#include <unistd.h>
#include <pthread.h>
#include "Protocol.hpp"
#include "Sock.hpp"

namespace ns_server
{
    using func_t = std::function<void(int)>;

    class TcpServer;

    class ThreadData
    {
    public:
        int _sockfd;
        TcpServer *_thisObj;
        uint16_t _clientport;
        std::string _clientip;
    public:
        ThreadData(const int &sockfd,TcpServer *thisObj,const uint16_t &port,const std::string &ip)
            :_sockfd(sockfd)
            ,_thisObj(thisObj)
            ,_clientport(port)
            ,_clientip(ip)
        {}

        ~ThreadData()
        {
            if(_sockfd>=0)
                close(_sockfd);
        }
    };

    class TcpServer
    {
    private:
        static void *Routine(void *args)
        {
            // 先进行线程分离
            pthread_detach(pthread_self());

            ThreadData *ptd=static_cast<ThreadData *>(args);

            ptd->_thisObj->Excute(ptd->_sockfd);

            close(ptd->_sockfd);
            delete ptd;
            return nullptr;
        }
    public:
        TcpServer(const uint16_t &port, const std::string &ip="0.0.0.0")
            : _port(port), _ip(ip)
        {
            // 创建套接字
            _listensock=_sock.Socket();
            // 进行绑定
            _sock.Bind(_listensock,_port,_ip);
            // 设置为监听状态
            _sock.Listen(_listensock);

            // std::cout<<"TcpServer success"<<std::endl;
        }

        ~TcpServer()
        {
            if(_listensock>=0)
                close(_listensock);
        }

        void AddService(func_t func)
        {
            _funcs.push_back(func);
        }

        void Excute(int sockfd)
        {
            for(auto &iter : _funcs)
            {
                iter(sockfd);
            }
        }

        void Start()
        {
            while(true)
            {
                uint16_t clientport;
                std::string clientip;
                // 获取连接
                int servicesock=_sock.Accept(_listensock,&clientport,&clientip);
                if(servicesock==-1)
                    continue;

                // std::cout<<"Accept success sockfd: "<<servicesock<<std::endl;

                // 创建线程来完成任务
                ThreadData *ptd=new ThreadData(servicesock,this,clientport,clientip);
                pthread_t tid;
                pthread_create(&tid,nullptr,Routine,(void *)ptd);
            }
        }

    private:
        uint16_t _port; // 端口
        std::string _ip;  // IP地址

        ns_sock::Sock _sock;       // 套接字相关的接口
        int _listensock = -1; // 套接字
        
        std::vector<func_t> _funcs; // 服务
        // func_t _func;     // 函数对象
    };
}
